<?php
/**
 * Created By PhpStorm
 * Author: patrick wu
 * Date: 2020/9/23
 * Time: 18:00
 */
namespace App\Service\Admin;

use App\Http\Model\Mysql\ProductModel;
use App\Http\Model\Mysql\ProductObjectModel;
use App\Http\Model\Mysql\AttributeModel;
use App\Http\Model\Mysql\AttributeValueModel;
use App\Http\Model\Mysql\ProductSpecsModel;
use App\Http\Model\Mysql\ShopModel;
use App\Http\Model\Mysql\BrandModel;
use App\Http\Model\Mysql\BoxModel;
use App\Utils\UploadAliOss;
use App\Utils\WechatUtil;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;


class ProductService extends BaseService
{
    /**
     * 商品列表
     * @param array $query  搜索条件
     * @param int $page 当前页码
     * @param int $size 每页数量
     * @param string $name 排序名称
     * @param string $sort 排序方式
     * @return array
     */
    public function productList(array $query, int $page = 1, int $size = 0, string $name = 'sorting', string $sort = 'desc')
    {
        $where['is_delete'] =   ProductModel::NOT_DELETE;
        $where['is_shelf']  =   $query['status'] ?? ProductModel::IS_SHELF;

        /**
         * 搜索条件
         */
        //店铺ID
        if (isset($query['shop_id'])) {
            $where['shop_id']   =   $query['shop_id'];
        }

        //品牌ID
        if (isset($query['brand_id'])) {
            $where['brand_id']  =   $query['brand_id'];
        }

        //供应商ID
        if (isset($query['supply_id'])) {
            $where['supply_id'] =   $query['supply_id'];
        }

        //商品编码
        if (isset($query['sku_code']) && !empty($query['sku_code'])) {
            $where['sku_code']  =   $query['sku_code'];
        }

        //商品标识符
        if (isset($query['unique_id']) && !empty($query['unique_id'])) {
            $where['unique_id']  =   $query['unique_id'];
        }

        //商品名称
        if (isset($query['good_name']) && !empty($query['good_name'])) {
            $where['name']      =   $query['good_name'];
        }

        /**
         * with([
        'shop'  =>  function ($query) {
        $query->where(['is_delete' => ShopModel::NOT_DELETE])->select(['id', 'shop_name', 'shop_contact']);
        },
        'brand' =>  function ($query) {
        $query->where(['is_delete' => BrandModel::NOT_DELETE])->select(['id', 'brand_name', 'brand_icon']);
        }
        ])->
         */
        $size   =   $size <= 0 ? self::PAGE_LIMIT : $size;
        $count  =   ProductModel::where($where)->count();

        $list   =   ProductModel::where($where)->limit($size)->offset(($page - 1) * $size)->select(['id', 'unique_id', 'shop_id', 'name', 'brand_id', 'sell_price', 'stock', 'cover_pic', 'virtual_sales', 'sku_code', 'real_sales', 'sorting', 'created_at', 'updated_at'])
                    ->orderBy($name, $sort)->get()->each(function (&$item) {
                        $item->create_time  =   $item->created_at->toDateTimeString();
                        $item->update_time  =   $item->updated_at->toDateTimeString();
                        unset($item->created_at);
                        unset($item->updated_at);
                    });

        if ($list->isEmpty()) {
            return [true, []];
        } else {
            return [true, [
                'count' =>  $count,
                'current'=> $page,
                'pages' =>  ceil($count / $size),
                'list'  =>  $list->toArray()
            ]];
        }
    }

    /**
     * 商品详情
     * @param int $good_id 商品ID
     * @return array
     */
    public function productDetail(int $good_id)
    {
        $detail =   ProductModel::with([
                        'shop'  =>  function ($query) {
                            $query->where(['is_delete' => ShopModel::NOT_DELETE])->select(['id', 'shop_name', 'shop_contact']);
                        },
                        'brand' =>  function ($query) {
                            $query->where(['is_delete' => BrandModel::NOT_DELETE])->select(['id', 'brand_name', 'brand_icon']);
                        },
                        'objectUrl' => function ($query) {
                            $query->where(['is_delete' => ProductObjectModel::NOT_DELETE])->select(['id', 'product_id', 'object_type', 'object_url']);
                        },
                        'specs' =>  function ($query) {
                            $query->select(['id', 'product_id', 'attr_list', 'sell_price', 'spec_pic', 'sku_code', 'stock']);
                        },
                    ])->where(['id' => $good_id, 'is_delete' => ProductModel::NOT_DELETE])->select(['id', 'unique_id', 'shop_id', 'supply_id', 'brand_id', 'name', 'sku_code', 'sell_price', 'original_price', 'cost_price',
                        'is_shelf', 'cover_pic', 'cover_video', 'virtual_sales', 'sorting', 'stock', 'reduce_type', 'unit', 'weight', 'limit_number', 'desc', 'spec_remark', 'detail', 'is_commission', 'is_box_commission', 'is_auto_send',
                    ])->first();
        if (empty($detail)) {
            return [false, '商品不存在'];
        } else {
            $spec_desc  =   [];
            /**
             * 商品规格数据的处理
             */
            if (!empty($detail->specs)) {
                foreach ($detail->specs as &$item) {
                    $attr_list   =   json_decode($item->attr_list, true);
                    $single_desc =   $single_value  =   [];
                    foreach ($attr_list as $key => $value) {
//                        $spec_desc[$key][]  =   $value;         //array_unique(array_merge($value, $spec_desc[$key] ?? []));
                        $single['name'] =   $key;
                        $single['value']=   $value;
                        $single_desc[]  =   $single;
                        if (isset($spec_desc[$key])) {
                            $spec_value =   array_merge(is_array($spec_desc[$key]['value']) ? $spec_desc[$key]['value'] : [$spec_desc[$key]['value']], [$single['value']]);
                            $spec_desc[$key]['value']   =   $spec_value;
                        } else {
                            $spec_desc[$key]=   $single;
                        }
                        $single_value[] =   $value;
                    }
                    $item->attr_list    =   $single_desc;
                    $item->attr_value   =   $single_value;
                }
            }

            $detail->spec_desc  =   array_values(array_map(function (&$item) {
                $item['value']  =   is_array($item['value']) ? array_unique($item['value']) : [$item['value']];
                return $item;
            }, $spec_desc));
            return [true, $detail];
        }
    }

    /**
     * 商品上下架
     * @param int $good_id  商品ID
     * @param int $status   操作状态 1：上架 0：下架
     * @return array
     */
    public function productOff(int $good_id, int $status)
    {
        $off_result =   ProductModel::where(['id' => $good_id])->update(['is_shelf' => $status]);
        if ($off_result) {
            return [true, '操作成功'];
        } else {
            return [false, '操作失败'];
        }
    }

    /**
     * 商品删除
     * @param int $good_id  商品ID
     * @return array
     */
    public function productDelete(int $good_id)
    {
        $delete_result  =   ProductModel::where(['id' => $good_id])->update(['is_delete' => ProductModel::IS_DELETE, 'delete_time' => Carbon::now()->timestamp]);
        if ($delete_result) {
            return [true, '删除成功'];
        } else {
            return [false, '删除失败'];
        }
    }

    /**
     * 商品添加
     * @param array $params  商品参数
     * @return array
     * @throws \Exception
     */
    public function productAdd(array $params)
    {
        /**
         * 上传多图到OSS服务器
         */
//        $upload_ali_oss =   new UploadAliOss();

        $insert['name']     =   $params['name'];
        $insert['shop_id']  =   $params['shop_id'];
        $insert['brand_id'] =   $params['brand_id'];
        $insert['unique_id']=   createUniqueID();
        $insert['supply_id']=   $params['supply_id'];
        $insert['sku_code'] =   $params['sku_code'];
        $insert['is_shelf'] =   $params['is_shelf'];
        $insert['is_hot']   =   ProductModel::NOT_HOT;
        $insert['is_member']=   0;
        $insert['sorting']  =   $params['sorting'];
        $insert['stock']    =   $params['stock'];
        $insert['unit']     =   $params['unit'] ?? '';
        $insert['weight']   =   $params['weight'] ?? 0;
        $insert['freight']  =   $params['freight'] ?? 1;
        $insert['desc']     =   $params['desc'] ?? '';
        $insert['cover_pic']=   empty($params['cover_pic']) ? '' : current($params['cover_pic']);
        $insert['detail']   =   json_encode($params['good_detail'] ?? [], JSON_UNESCAPED_UNICODE);
        $insert['version']  =   createUniqueID();
        $insert['is_delete']=   ProductModel::NOT_DELETE;
        $insert['spec_remark']      =   $params['remark'] ?? '';
        $insert['is_commission']    =   $params['is_commission'];
        $insert['is_box_commission']=   $params['is_box_commission'];
        $insert['is_connection']    =   0;
        $insert['is_auto_send']     =   $params['is_auto_send'];
        $insert['reduce_type']      =   $params['reduce_type'] ?? 1;
        $insert['sell_price']       =   $params['sell_price'] ?? 0;
        $insert['cost_price']       =   $params['cost_price'] ?? 0;
        $insert['limit_number']     =   $params['limit'];
        $insert['virtual_sales']    =   $params['virtual'];
        $insert['original_price']   =   $params['original_price'] ?? 0;
        $insert['created_at']       =   $insert['updated_at']    =   Carbon::now()->timestamp;

        /*$setting_path   =   Config::get('upload.local_path');
        $upload_path    =   public_path($setting_path);*/

        DB::beginTransaction();

        try {
            $product_id =   DB::table('mini_product')->insertGetId($insert);

            /**
             * 多图插入
             */
            if (!empty($params['cover_pic'])) {
                $total_object   =   $upload_object  =   [];

                /*foreach ($params['good_detail'] as $item) {
                    $object_pic      =   sha1($item->getClientOriginalName() . createRandomNumber()) . '.' . $item->extension();
                    $item->move($upload_path, $object_pic);

                    $upload_object[$object_pic] =    $upload_path . DIRECTORY_SEPARATOR . $object_pic;
                }

                [$flag, $result]=   $upload_ali_oss->uploadFile($upload_object);

                if ($flag) {
                    foreach ($upload_object as $local) {
                        @unlink($local);
                    }
                    $upload_object  =   $result;
                } else {
                    foreach ($upload_object as $key => &$item) {
                        $item   =   URL::asset($setting_path . '/' . $key);
                    }
                }*/

                foreach ($params['cover_pic'] as $one_object) {
                    $single['product_id']   =   $product_id;
                    $single['object_type']  =   ProductObjectModel::PIC_OBJECT;
                    $single['object_url']   =   $one_object;
                    $single['created_at']   =   $single['updated_at']   =   Carbon::now()->timestamp;
                    $total_object[]         =   $single;
                }
                unset($single);
                DB::table('mini_product_object_url')->insert($total_object);
            }

            /**
             * 多分类插入
             */
            if (!empty($params['cat_id'])) {
                $total_cat  =   [];
                foreach ($params['cat_id'] as $cat_id) {
                    $single['product_id']   =   $product_id;
                    $single['cat_id']       =   $cat_id;
                    $single['created_at']   =   $single['updated_at']   =   Carbon::now()->timestamp;
                    $total_cat[]            =   $single;
                }
                unset($single);
                DB::table('mini_product_cat')->insert($total_cat);
            }

            /**
             * 多规格插入
             */
            if (!empty($params['good_spec'])) {
                $total_spec =   [];

                $mini_sell_price    =   current($params['good_spec'])['sell_price'] ?? 0;
                $mini_cost_price    =   0;
                $mini_origin_price  =   0;
                foreach ($params['good_spec'] as $good_spec) {
                    $spec_value =   json_decode($good_spec['attr_value'], true);

                    if (!empty($spec_value)) {
                        /**
                         * 保存多个属性值
                         */
                        foreach ($spec_value as $key => $value) {
                            AttributeValueModel::updateOrCreate([
                                'attr_id'   =>  AttributeModel::where(['attr_name' => $key])->value('id') ?? 0,
                                'attr_name' =>  $key,
                                'attr_value'=>  $value,
                                'is_delete' =>  AttributeValueModel::NOT_DELETE,
                            ], [
                                'attr_value'    =>  $value,
                                'is_delete'     =>  AttributeValueModel::NOT_DELETE
                            ]);
                        }
                    }

                    $single['product_id']   =   $product_id;
                    $single['attr_list']    =   json_encode($spec_value, JSON_UNESCAPED_UNICODE);
                    $single['sell_price']   =   $good_spec['sell_price'];
                    $single['original_price']=  $good_spec['original_price'];
                    $single['cost_price']   =   $good_spec['cost_price'];
                    $single['sku_code']     =   $good_spec['sku_code'];
                    $single['stock']        =   $good_spec['stock'];
                    $single['spec_pic']     =   $good_spec['spec_pic'];
                    $single['created_at']   =   $single['updated_at']   =   Carbon::now()->timestamp;

                    if ($mini_sell_price >= $good_spec['sell_price']) {
                        $mini_sell_price    =   $good_spec['sell_price'];
                        $mini_cost_price    =   $good_spec['cost_price'];
                        $mini_origin_price  =   $good_spec['original_price'];
                    }

                    /*$spec_pic      =   sha1($good_spec['spec_pic']->getClientOriginalName() . createRandomNumber()) . '.' . $good_spec['spec_pic']->extension();
                    $good_spec['spec_pic']->move($upload_path, $spec_pic);

                    $upload_spec[$spec_pic] =   $upload_path . DIRECTORY_SEPARATOR . $spec_pic;
                    [$flag, $upload_result] =   $upload_ali_oss->uploadFile($upload_spec);
                    $flag ? @unlink($upload_spec[$spec_pic]) : '';
                    $single['spec_pic']     =   $flag ? $upload_result[$spec_pic] : URL::asset($setting_path . '/' . $spec_pic);*/

                    $total_spec[]   =   $single;
                }
                unset($single);
                DB::table('mini_product')->where(['id' => $product_id])->update(['sell_price' => $mini_sell_price, 'cost_price' => $mini_cost_price, 'original_price' => $mini_origin_price]);
                DB::table('mini_product_specs')->insert($total_spec);
            }

            DB::commit();
            return [true, '添加成功'];
        } catch (\Exception $e) {
            DB::rollBack();
            return [false, $e->getMessage()];
        }

    }

    /**
     * 商品编辑
     * @param array $params 编辑条件
     * @param int $good_id  商品ID
     * @return array
     */
    public function productEdit(array $params, int $good_id)
    {
        $insert['name']     =   $params['name'];
        $insert['shop_id']  =   $params['shop_id'];
        $insert['brand_id'] =   $params['brand_id'];
        $insert['unique_id']=   createUniqueID();
        $insert['supply_id']=   $params['supply_id'];
        $insert['sku_code'] =   $params['sku_code'];
        $insert['is_shelf'] =   $params['is_shelf'];
        $insert['is_hot']   =   ProductModel::NOT_HOT;
        $insert['is_member']=   0;
        $insert['sorting']  =   $params['sorting'];
        $insert['stock']    =   $params['stock'];
        $insert['unit']     =   $params['unit'] ?? '';
        $insert['weight']   =   $params['weight'] ?? 0;
        $insert['freight']  =   $params['freight'] ?? 1;
        $insert['desc']     =   $params['desc'] ?? '';
        $insert['cover_pic']=   empty($params['cover_pic']) ? '' : current($params['cover_pic']);
        $insert['detail']   =   json_encode($params['good_detail'] ?? [], JSON_UNESCAPED_UNICODE);
        $insert['spec_remark']      =   $params['remark'] ?? '';
        $insert['is_commission']    =   $params['is_commission'];
        $insert['is_box_commission']=   $params['is_box_commission'];
        $insert['is_connection']    =   0;
        $insert['is_auto_send']     =   $params['is_auto_send'];
        $insert['reduce_type']      =   $params['reduce_type'] ?? 1;
        $insert['sell_price']       =   $params['sell_price'] ?? 0;
        $insert['cost_price']       =   $params['cost_price'] ?? 0;
        $insert['limit_number']     =   $params['limit'];
        $insert['virtual_sales']    =   $params['virtual'];
        $insert['original_price']   =   $params['original_price'] ?? 0;
        $insert['updated_at']    =   Carbon::now()->timestamp;

        DB::beginTransaction();

        try {
            DB::table('mini_product')->where(['id' => $good_id])->update($insert);

            /**
             * 多图插入
             */
            if (!empty($params['cover_pic'])) {
                $total_object   =   $upload_object  =   [];

                foreach ($params['cover_pic'] as $one_object) {
                    $single['product_id']   =   $good_id;
                    $single['object_type']  =   ProductObjectModel::PIC_OBJECT;
                    $single['object_url']   =   $one_object;
                    $single['created_at']   =   $single['updated_at']   =   Carbon::now()->timestamp;
                    $total_object[]         =   $single;
                }
                unset($single);
                DB::table('mini_product_object_url')->where(['product_id' => $good_id])->update(['is_delete' => ProductObjectModel::IS_DELETE]);
                DB::table('mini_product_object_url')->insert($total_object);
            }

            /**
             * 多分类插入
             */
            if (!empty($params['cat_id'])) {
                $total_cat  =   [];
                foreach ($params['cat_id'] as $cat_id) {
                    $single['product_id']   =   $good_id;
                    $single['cat_id']       =   $cat_id;
                    $single['created_at']   =   $single['updated_at']   =   Carbon::now()->timestamp;
                    $total_cat[]            =   $single;
                }
                unset($single);
                DB::table('mini_product_cat')->where(['product_id' => $good_id])->delete();
                DB::table('mini_product_cat')->insert($total_cat);
            }

            /**
             * 多规格插入
             */
            if (!empty($params['good_spec'])) {
                $total_spec =   [];
                $mini_sell_price    =   current($params['good_spec'])['sell_price'] ?? 0;
                $mini_cost_price    =   0;
                $mini_origin_price  =   0;

                foreach ($params['good_spec'] as $good_spec) {
                    $spec_value =   json_decode($good_spec['attr_value'], true);

                    if (!empty($spec_value)) {
                        /**
                         * 保存多个属性值
                         */
                        foreach ($spec_value as $key => $value) {
                            AttributeValueModel::updateOrCreate([
                                'attr_id'   =>  AttributeModel::where(['attr_name' => $key])->value('id') ?? 0,
                                'attr_name' =>  $key,
                                'attr_value'=>  $value,
                                'is_delete' =>  AttributeValueModel::NOT_DELETE,
                            ], [
                                'attr_value'    =>  $value,
                                'is_delete'     =>  AttributeValueModel::NOT_DELETE
                            ]);
                        }
                    }

                    $single['product_id']   =   $good_id;
                    $single['attr_list']    =   json_encode($spec_value, JSON_UNESCAPED_UNICODE);
                    $single['sell_price']   =   $good_spec['sell_price'];
                    $single['original_price']=  $good_spec['original_price'];
                    $single['cost_price']   =   $good_spec['cost_price'];
                    $single['sku_code']     =   $good_spec['sku_code'];
                    $single['stock']        =   $good_spec['stock'];
                    $single['spec_pic']     =   $good_spec['spec_pic'];
                    $single['created_at']   =   $single['updated_at']   =   Carbon::now()->timestamp;

                    $total_spec[]   =   $single;

                    if ($mini_sell_price >= $good_spec['sell_price']) {
                        $mini_sell_price    =   $good_spec['sell_price'];
                        $mini_cost_price    =   $good_spec['cost_price'];
                        $mini_origin_price  =   $good_spec['original_price'];
                    }
                }
                unset($single);

                /**
                 * 修改主规格的售价和原价
                 */
                DB::table('mini_product')->where(['id' => $good_id])->update(['sell_price' => $mini_sell_price, 'cost_price' => $mini_cost_price, 'original_price' => $mini_origin_price]);
                DB::table('mini_product_specs')->where(['product_id' => $good_id])->delete();
                DB::table('mini_product_specs')->insert($total_spec);
            }

            DB::commit();
            return [true, '修改成功'];
        } catch (\Exception $e) {
            DB::rollBack();
            return [false, $e->getMessage()];
        }
    }

    /**
     * 商品生成二维码
     * @param int $good_id
     * @param int $box_id
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function productCode(int $good_id, int $box_id)
    {
        $good_unique    =   ProductModel::where(['id' => $good_id])->value('unique_id');
        $box_unique     =   BoxModel::where(['id' => $box_id])->value('unique_id');

        $admin_info     =   request()->post('admin_user');
        [$flag, $result]    =   WechatUtil::getUnlimitedCode(['scene' => 'good', 'page' => 'page/goods/detail?good_id=' . $good_unique . '&box_id=' . $box_unique], $admin_info['user_id']);
        if ($flag && isset($result['img_path'])) {
            return [true, file_get_contents($result['img_path'])];
        } else {
            return [false, '二维码生成失败'];
        }
    }

}
